package cn.zyjblogs.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * Scattering： 将数据写入到Buffer时，可以采用buffer数组，依次写入
 * Gethering： 从buffer读取数据时，可以采用buffer数组，依次读取
 */
public class ScatteringAndGetheringTest {
    public static void main(String[] args) {
        //使用 ServerSocketChannel 和 SocketChannel 网络
        try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
            InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);
            //绑定端口到socket，并启动
            serverSocketChannel.socket().bind(inetSocketAddress);
            //创建buffer数组
            ByteBuffer[] byteBuffers = new ByteBuffer[2];
            byteBuffers[0] = ByteBuffer.allocate(5);
            byteBuffers[1] = ByteBuffer.allocate(3);

            //等待客户端连接(telnet)
            SocketChannel socketChannel = serverSocketChannel.accept();
            //假设从客户端接受8个字节
            int messageLenght = 8;
            //循环读取
            while (true) {
                int byteRead = 0;
                while (byteRead < messageLenght) {
                    long read = socketChannel.read(byteBuffers);
                    //累计读取的字节数
                    byteRead += read;
                    System.out.println("byteRead=" + byteRead);
                    //使用流打印 当前buffer的postion 和limit
                    Arrays.asList(byteBuffers).stream().map(buffer -> {
                        return "postion=" + buffer.position() + ", limit=" + buffer.limit();
                    }).forEach(System.out::println);
                }
                //将所有的buffer进行flip
                Arrays.asList(byteBuffers).forEach(Buffer::flip);
                long byteWrite = 0;
                //将数据读取出到客户端
                while (byteWrite < messageLenght) {
                    long write = socketChannel.write(byteBuffers);
                    byteWrite += write;
                }
                //将所有的buffer 进行clear
                Arrays.asList(byteBuffers).forEach(Buffer::clear);
                System.out.println("byteRead:=" + byteRead + " byteWrite" + byteWrite + " messageLenght" + messageLenght);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
